package com.sikaryofficial.system.manager;

import com.sikaryofficial.system.constant.RedisCacheKey;
import com.sikaryofficial.system.domain.SysNotice;
import com.sikaryofficial.system.domain.SysUserNotice;
import com.sikaryofficial.system.domain.dto.SysNoticeWithUser;
import com.sikaryofficial.system.domain.dto.UserNoticeReq;
import com.sikaryofficial.system.domain.mapping.SysNoticeMapping;
import com.sikaryofficial.system.service.ISysNoticeService;
import com.sikaryofficial.system.service.ISysUserNoticeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class SysNoticeManager {

    @Autowired
    private ISysNoticeService sysNoticeService;

    @Autowired
    private ISysUserNoticeService sysUserNoticeService;

    public List<SysNotice> selectNoticeList(SysNotice notice) {
        return sysNoticeService.selectNoticeList(notice);
    }

    public SysNoticeWithUser selectNoticeById(Long noticeId) {
        SysNotice sysNotice = sysNoticeService.selectNoticeById(noticeId);
        if (sysNotice == null) {
            return new SysNoticeWithUser();
        }
        SysNoticeWithUser sysNoticeWithUser = SysNoticeMapping.INSTANCE.coverToResp(sysNotice);
        List<SysUserNotice> userNoticeList = sysUserNoticeService.lambdaQuery()
                .eq(SysUserNotice::getNoticeId, noticeId)
                .list();
        if (userNoticeList != null && !userNoticeList.isEmpty()) {
            sysNoticeWithUser.setUserIds(userNoticeList.stream().map(SysUserNotice::getUserId).collect(Collectors.toList()));
        }
        return sysNoticeWithUser;
    }

    @Transactional
    @CacheEvict(value = RedisCacheKey.NOTICE_USER_LIST, allEntries = true)
    public int insertNotice(SysNoticeWithUser notice) {
        SysNotice sysNotice = SysNoticeMapping.INSTANCE.covertToEntity(notice);
        int result = sysNoticeService.insertNotice(sysNotice);
        saveUserNotice(sysNotice.getNoticeId(), notice.getUserIds());
        return result;
    }

    @Transactional
    @CacheEvict(value = RedisCacheKey.NOTICE_USER_LIST, allEntries = true)
    public int updateNotice(SysNoticeWithUser notice) {
        SysNotice sysNotice = SysNoticeMapping.INSTANCE.covertToEntity(notice);
        int result = sysNoticeService.updateNotice(sysNotice);
        sysUserNoticeService.lambdaUpdate()
                .eq(SysUserNotice::getNoticeId, notice.getNoticeId())
                .remove();
        saveUserNotice(sysNotice.getNoticeId(), notice.getUserIds());
        return result;
    }

    /**
     * 保存用户和公告的关联关系
     * @param noticeId  公告ID
     * @param userIds   用户ID集合
     */
    private void saveUserNotice(Long noticeId, List<Long> userIds) {
        if (userIds == null || userIds.isEmpty()) {
            return;
        }
        List<SysUserNotice> userNoticeList = userIds.stream().map(userId -> {
            SysUserNotice sysUserNotice = new SysUserNotice();
            sysUserNotice.setNoticeId(noticeId);
            sysUserNotice.setUserId(userId);
            return sysUserNotice;
        }).collect(Collectors.toList());
        sysUserNoticeService.saveBatch(userNoticeList);
    }

    @Transactional
    @CacheEvict(value = RedisCacheKey.NOTICE_USER_LIST, allEntries = true)
    public int deleteNoticeByIds(Long[] noticeIds) {
        int result = sysNoticeService.deleteNoticeByIds(noticeIds);
        sysUserNoticeService.lambdaUpdate()
                .in(SysUserNotice::getNoticeId, Arrays.asList(noticeIds))
                .remove();
        return result;
    }

    @Cacheable(value = RedisCacheKey.NOTICE_USER_LIST, key = "#req.userId + ':' + #req.hashCode()")
    public List<SysNotice> listUserNotice(UserNoticeReq req) {
        return sysNoticeService.listUserNotice(req);
    }
}
